
昨天那份訂單取消程式,測試都過了,退款規則卻還沒有人確認。我把缺件寫成退件單,交回作者處理。
昨天,我們決定讓 AI 先替變更分流:簡單修改交給工具檢查,一般修改由 AI 審查,涉及核心業務與重要例外的,再送到 Owner 面前。今天要把這套判準寫進 Claude Code,看看它能不能把修改送到對的地方。
先看一次真實的維運退件,找出判斷需要哪些材料,再回到昨天的訂單取消案例。兩個案例不同,問的是同一件事:這份交付的判斷,有沒有可以核對的依據?
上個月,我把一項維運分析工具的開發任務交給 Claude Code:替既有排查 Agent 補上輸入整理與結果彙整,讓工單進入分析,交回結構化報告。它以 headless 模式執行,環境提供 Atlassian MCP 工具查資料。
交付摘要回報單元測試通過,但另一個前提藏在報告裡:即時資料不可用,所以改用本機快照。
我心裡的 OS 是:「燈愣!!!怎麼可能,是不是想騙我?」
我另外開一次非互動執行,呼叫同一組工具,查詢正常。這不能還原它當時的服務狀態,但回頭核對紀錄,確實沒有支持「不可用」的實際呼叫。問題是它沒查證,就據此換了資料來源。
退件單這樣寫:
缺件:未實際查證,就宣稱即時資料不可用並改用快照。
動作:先呼叫 getAccessibleAtlassianResources 與 getJiraIssue 查該筆工單。
證據:工具名稱、查詢對象、實際回傳或錯誤。
重審:核對實測結果,再判斷替代來源是否適用。
我把這條要求補進專案的 CLAUDE.md,也寫進任務規格當驗收條件。重跑後,報告開頭附了實際回傳,資料來源改標 live。它還發現即時工單與本機快照的狀態不一致,這次把衝突列為待人確認,沒有自行選一邊。
這次留下的要求很簡單:說「查不到」,就把查過什麼、回了什麼交出來。 紀錄能確認的是缺少查證,不是有意欺騙;補齊這項缺件,也不代表整個工具已驗收通過。
這次是我自己發現它沒查過。但如果每份交付都要我從頭查,Review 還是會卡在人身上。延續昨天的分流方法,我想讓 Claude 先核對材料、指出缺件,再判斷哪些問題需要送人。
問題也跟著來了:剛發現 Claude 沒查過就下結論,為什麼還讓它守門?
它的判級也要交出依據。 作者說「測試過了」,審查時就找執行輸出;作者說「退款規則已確認」,就找規則與確認來源。找不到要列缺件,不能替作者補一個合理的故事。這裡的 evidence,就是能拿來核對的材料。
AI 可以先替人整理需要查的位置,但多一個 AI 並不保證正確。因此,哪些條件一定要人審,必須先寫清楚;判級結果也要用案例核對,必要條件還要由程式檢查。維運退件讓我看見「只讀交付摘要」的問題,接下來才是把這個教訓用在 PR 分流。
三層是三種處理路徑,不是每份 PR 都要排隊走完三關。
| AI 判級 | 例子 | 後續處理 |
|---|---|---|
| L1:工具檢查 | 政策允許的純文件或格式修改,沒有核心規則變動 | 跑對應檢查;符合預先訂好的接受條件,才可走簡化流程 |
| L2:AI 審查 | 未涉及必要人審範圍,但需要比對需求、程式與測試的一般修改 | AI 查核依據,缺件退回;發現核心影響或無法判斷就升級 |
| L3:Owner 決定 | 付款、權限、核心狀態轉換與重要例外 | AI 整理命中原因、影響與待決問題,交給有權決定的人 |
AI 是入口守門員,Owner 處理需要人決定的核心問題。 低風險能否結束流程,由事先訂好的條件與實際檢查結果決定,不是 AI 說一句「沒問題」就合併。
但「核心的交給人」對 Claude 仍然太模糊。哪些檔案算核心?碰到付款就要人審,還是只有真正扣款才算?文件修改一定低風險嗎?這些要先由團隊決定,不能每次讓模型自己解釋。
我把這些判準整理成一份獨立的文字設定檔,命名為 routing-policy.yml。routing 是分流,policy 是政策;YAML 則是用欄位與清單保存設定的格式。這個檔案回答的是:看到什麼條件,應該走哪一條審查路徑?
例如「新增內容出現付款旗標,要送 Owner」,就寫成關鍵字條件;「只改少量文件,而且必要檢查都通過」,才列入簡化範圍。獨立成檔,是為了讓大家能在 Git 裡討論與追蹤規則變動,也讓後續的 AI 指示與檢查程式有同一份依據。檔案不會自行執行,還需要明確安排誰讀它、怎麼套用。
下面是本示範的政策內容:
owner_required:
paths: ["src/Orders/Cancellation*", "src/Payments/**", "src/Auth/**", "db/migrations/**"]
keywords_in_diff: ["Refund", "Paid", "authorized", "Cancelled =", "DROP TABLE"]
diff_lines_over: 400
low_risk: { allow_paths: ["docs/**", "**/*.md"], require_checks_pass: true, max_diff_lines: 50 }
unclear: escalate
Owner 條件優先;未命中才判斷能否走簡化路徑,其餘能明確分類的一般修改走 L2,不明就升級。文件路徑也不能直接當成安全證明,例如文件本身改了核心規則,就不該只看副檔名。400 與 50 行是示範門檻,要依團隊工作調整。
以昨天的訂單取消為例,只要修改命中付款或核心狀態條件,就應送 L3。補齊文件不會解除必要人審。有了這個預期,接下來才能核對 Claude 的判斷,而不是看它的回答順不順眼。這份 YAML 目前是政策資料,尚未接成自動分流。
以下切回 Day 3 的訂單取消合成案例,與上個月的維運任務分開。政策說明怎麼分流,接著還要讓 Claude 看見「這次到底改了什麼」。我把審查材料放在同一個資料夾:
| 檔案 | 裡面放什麼 | Claude 要拿它核對什麼? |
|---|---|---|
ticket.md |
這次需求、適用規則與版本 | 原本要求做到哪裡?退款是明文要求,還是實作自行加入? |
diff.patch |
程式修改前後的差異;+ 是新增行,- 是刪除行 |
實際改了哪些行?有沒有碰到付款或狀態轉換? |
PR.md |
作者的修改摘要、風險自評、驗證說明與待確認事項 | 作者說的,是否與需求、程式和證據對得起來? |
Program.cs |
本合成案例的程式與測試 | 測試實際檢查什麼?預期行為有沒有規則依據? |
PR 是 Pull Request,也就是提出程式變更、請求審查的交付。這裡的 PR.md 是為了本機實驗,把 PR 描述存成 Markdown;ticket.md 是需求快照,diff.patch 是差異快照。它們是本案例的材料命名,不是 Claude Code 強制要求的檔名。在真正的 repo,也可以從工單與 Git 取得對應內容。
這幾份材料要互相比對:作者在 PR.md 勾低風險,不代表 diff.patch 就沒碰付款;Program.cs 的測試通過,也不代表 ticket.md 已同意退款規則。實際執行輸出則是另外一份證據,測試原始碼本身不能取代它。
編譯、格式、測試與掃描由工具執行,留下結果供判級與審查使用。涉及核心業務的修改一樣需要這些基本檢查;分流決定的是誰要進一步判斷,不是高層可以跳過測試。
昨天那份程式的測試,是另一個 AI 代理工具 Codex 在本機以 .NET 9 執行的,七組情境十八個斷言,輸出最後兩行是 ALL TESTS PASSED 與 exit=0。這份輸出證明測試涵蓋的行為,不證明退款規則對。而下面審查目錄的 PR 只有測試通過的文字,沒有附上這份原始輸出;這也是要讓 Claude 找出的缺件。
我用 PR 範本收集這些材料。範本本身不會阻擋缺件,是否填齊、內容是否有依據,還要由檢查程式與審查核對。PULL_REQUEST_TEMPLATE.md 就是昨天的五項交接契約變成表單:
1. 可追溯 需求/工單版本、規則位置、修改的檔案
2. 獨立證據 驗收預期的規則依據(不是「模型這樣寫」)、實際執行輸出
3. 語意邊界 新增的假設、例外、已確認/待確認各由誰確認
4. 影響範圍 呼叫端、權限或資料來源、尚未驗證的路徑
5. 可解釋 接受的範圍、退回的範圍與理由、負責人(Reviewer 填)
判級自評:low / normal / owner-required
觸及:[ ] 金額/付款 [ ] 授權/權限 [ ] 狀態轉換規則 [ ] 資料遷移 [ ] 以上皆非
昨天那份 PR 照這張表填,「規則位置」和「驗收預期的規則依據」兩格是空的,判級自評填了 low,「觸及」勾了「以上皆非」。空格與自評都是 AI 判級時要核對的訊號。
我先用一般提示,請 Claude 對照需求與修改,找出缺件與需要 Owner 的問題,還沒有加入完整分流政策:
審查目前目錄的 PR。檔案:PR.md(作者說明)、ticket.md(需求)、diff.patch(修改)、Program.cs(測試)。
只讀,不修改、不執行任何東西。
回一個 JSON:verdict 是 PASS、NEEDS_EVIDENCE、OWNER_REQUIRED 三者之一;
findings 每條有 claim、source(檔名加行號或引句)、missing、severity(block/ask/note);
owner_questions 列出要問負責人的事。
claude -p 讓 Claude 接收一段提示、執行後回傳結果,省去互動問答,方便由腳本重複執行並保存紀錄。這次只開 Read(讀檔)、Grep(搜尋內容)、Glob(找檔案):我要看它怎麼審現有交付,不讓它邊審邊改程式或補跑測試。 缺少的執行證據,應在結果裡指出。
其中一筆缺件審查回報 OWNER_REQUIRED,列出以下六條發現(依保存的審查結果摘述):
| 嚴重度 | Claude 指出的內容 | 來源 |
|---|---|---|
| block | 作者自評判級為 low,且勾「以上皆非」而非「狀態轉換規則」 | PR.md:25 |
| block | 新增假設「已出貨時不丟例外、已取消再取消視為無事發生」未經確認 | PR.md:14–15 |
| ask | 規則位置未填 | PR.md:6 |
| ask | 驗收預期的規則依據未填 | PR.md:10 |
| ask | 呼叫端與尚未驗證的路徑未填 | PR.md:18–19 |
| ask | 「七組情境十八個斷言 PASS」是唯一的驗證證據 | PR.md:11 |
重點是第一條:作者勾了低風險,程式卻碰到付款與狀態轉換。Claude 能指出這種矛盾,但重跑不一定得到相同結論。要固定「付款修改必須人審」的要求,就得明寫政策,不能期待模型每次自行推測。
前面幾份檔案是「這次要審的材料」,但 Claude 還需要一份「審查時照什麼步驟做」的工作說明。我把這份說明寫成 Claude Code 的 skill,入口檔名是 SKILL.md。
SKILL.md 放的是給 Claude 的指示:先讀哪些檔、按什麼順序查、缺資料時怎麼處理、最後交回哪些欄位。它不是需求文件,也不負責宣告這次修改已經通過。檔案開頭的 frontmatter 設定 skill 的名稱、用途與工具限制,正文才是審查步驟。
兩者的分工是:routing-policy.yml 保存「什麼情況走哪層」;SKILL.md 說明「讀取政策與材料後,如何查核並回覆」。

整合示意,省略程式與執行輸出。實際讀檔與判斷由 Claude Code 執行,SKILL.md 是它的工作說明;灰色虛線代表政策檔尚未接入,整合後的判級仍須驗證。
下面是準備把獨立政策檔接入 skill 的指示範本:
先讀指定版本的 routing-policy.yml、PR.md、ticket.md、diff.patch 與檢查結果。
1. 查 Owner 條件;命中就送 L3,列出條件、來源位置與待 Owner 決定的問題。
2. 未命中才查 low_risk;條件及必要檢查皆滿足,才建議走 L1。
3. 其餘可明確分類的一般修改走 L2,依五問對照宣稱與證據。
4. 缺件要列出誰補什麼;分類不明或發現核心影響,升級 L3。
輸出建議層級、命中理由、證據、缺件與下一步。
不得自行解除必要人審;不要把分類、檢查通過與合併混成一個結論。
這段是整合目標,不是前面一般提示的原文。現有 review-pr 的 SKILL.md 已有一部分:先查付款、權限、狀態等關鍵字,要求 OWNER_REQUIRED,再核對五問與證據。但 v0.1.0 把條件寫在 skill 裡,尚未讀取 YAML,也沒有完整輸出 L1/L2/L3。
為什麼還要包成 plugin?只把提示留在自己的對話裡,每個同事都要重新複製、修改,規則很快就會各有一版。我想把本機試跑、核對過的方法整理成有名稱、有版本的套件,讓團隊成員能載入同一份 skill;以後修改查法,也有共同的版本可以追蹤。
plugin 解決的是「怎麼把方法交給大家用」。試跑證明到哪裡,仍要看後面的結果,不能因為包成套件就當成全部驗證完成。本次已用本機 plugin 載入驗證,團隊分發是接下來的用途。檔案結構如下:
review-kit/
├── .claude-plugin/plugin.json 套件名稱與版本
└── skills/review-pr/SKILL.md 讀取材料、判級條件與查核指示
先用現有版本核對 Owner 分流。安裝 Claude Code CLI 並登入後,在本 repo 根目錄用 PowerShell 執行:
$reviewPlugin = (Resolve-Path 'examples/kit-review/plugin/review-kit').Path
Set-Location 'examples/kit-review/plugin-lab/fixtures/pr-A'
claude --plugin-dir $reviewPlugin
進入 Claude Code 後輸入:
/review-kit:review-pr
審查目前目錄的 PR.md、ticket.md、diff.patch 與 Program.cs。
只讀材料,依 skill 回覆;列出需要 Owner 的原因、來源與缺件。
先確認指定 skill 已載入,再核對它是否指出付款或狀態條件、引用哪裡、請 Owner 決定什麼。這條互動操作是給讀者的重現方式,既有紀錄使用非互動執行;回覆不一定逐字相同。
plugin-lab 保存了缺件版、補件版的審查與重跑紀錄。把有效版本的結果合在一起看,結論如下;補件版的 Owner 確認與 CI 編號都是教學設定,不是真實簽核或執行證據。
| 審查方式 | 材料 | 整體結果 | 可以確認什麼 |
|---|---|---|---|
| 一般提示 | 缺件版 | 兩次分別回報 OWNER_REQUIRED 與 NEEDS_EVIDENCE | 能找到缺件,但沒有每次都保留必要人審要求 |
| 一般提示 | 補件版 | 原試跑與重跑皆為 NEEDS_EVIDENCE | 仍要求補證據,發現內容不同;沒有直接放行 |
| 載入 skill | 缺件版 | 原試跑與重跑皆為 OWNER_REQUIRED | 這兩次都保留付款與狀態變更的人審要求 |
| 載入 skill | 補件版 | 一次有效版本試跑回報 OWNER_REQUIRED,後續未複驗 | 文件補齊後仍要求人審,並指出確認與執行證據未附上 |
具體的收穫,是 skill 能把「請人看一下」寫成可處理的補件:
diff.patch:28–30把已付款接成退款旗標,但 ticket 沒有退款規則,PR 的確認欄位也空白。請 Owner 確認這個旗標代表「需要退款」還是「已退款」,以及部分付款是否在範圍內。
這段依 skill 缺件結果翻譯摘述。要補的是業務規則,不是再加一個沿用同樣假設的測試。即使補件版把五項材料填滿,模型仍指出 CI log、Owner 確認與呼叫端證據沒有附上;已填不等於已核實。
失敗也要算進來:曾有一份補件材料的 ticket 與 PR 版本不一致,一般提示有抓到,skill 卻漏掉。此外,skill 有引用介面骨架來支持分類的情況,引用內容仍要核對,不能把介面欄位當成業務已確認。
目前能留下來的是一份有實跑、有來源、也保留漏項的 Owner 查核方法。skill 內的規則仍由模型遵守;L1/L2 分流、完整派送與團隊減載尚待驗證。本文結果整理自保存的本機執行紀錄;原始紀錄不在本文提供連結。
本機要手動準備材料、呼叫 Claude。下一步,是讓 PR 建立或更新時自動做這些事,結果直接回到開發者面前。以下是接入計畫,尚未部署。
先補齊三條路的案例:符合簡化條件的修改、需要 AI 理解的一般修改、涉及付款的核心修改。還要測分類不明、缺資料與執行失敗,並故意把付款修改自評為 low,確認不能因此免除必要人審。獨立政策檔也要先接入,才能驗它與 skill 的判斷是否一致。
平台就選團隊原本放 repo 的地方,不必同時做兩套:
| Repo 所在平台 | 自動執行與回報 | 後續合併條件 |
|---|---|---|
| GitHub | GitHub Actions 呼叫 Claude Code,保存結果並回貼 PR | 必要狀態檢查、CODEOWNERS 與保護規則 |
| Azure Repos | Azure Pipelines 執行 Claude Code CLI,另寫回報 PR 的整合 | Branch policies 的 Build validation、必要 Reviewer;若使用外部狀態則接 Status checks |
GitHub 可參考 Claude Code Action 官方說明;Azure Repos 的管線與必要審查接法見 Microsoft 分支政策文件。Action 是 GitHub 的整合方式,不能直接把同一份 workflow 當成 Azure Pipelines 設定。
我會先讓它自動回報審查結果:取得 PR 當前版本的需求與 diff、基本檢查結果,載入固定版本的政策與 skill,再回貼建議層級、理由、缺件與下一步。更新程式後要重新核對,不能沿用舊版本的結論。這一階段先觀察是否讀對材料、漏判或誤報,不讓新增的 AI 結論自動取代原有人審。
確認結果與失敗處理後,再把它接成合併限制。必要人審條件由程式同步檢查,AI 可以升級,不能降級;缺件、審查失敗或必要 Owner 尚未確認,都不能當成通過。現有 checker 只寫出結果,即使 pass:false 也不會自行讓程序失敗,接 CI 時還要把不符結果轉成失敗狀態,並在平台設為必要檢查。
參考資料:
-p、--tools、--output-format 參數;Claude Code GitHub Actions:workflow 範本的官方參考。